iT邦幫忙

2023 iThome 鐵人賽

DAY 23
0
SideProject30

HOW TO GO系列 第 23

23. Entity Component System (2)

  • 分享至 

  • xImage
  •  

接續上一篇 22. Entity Component System (1),如果以 Go 要如何實現呢?

這邊先找到幾個開源項目,參考別人是如何實作

概念

  • 基本概念是會定義一個 world 管理整個系統
  • world 可能包含多個 entity,然後由 world 來執行各個 system
  • 因為 sysyem 是依序執行所有執行先後問題,因此需要確認邏輯上有沒有矛盾

簡單範例會是這樣

package main

import "fmt"

type EntityID int

type PositionComponent struct {
	X, Y float64
}

type RenderComponent struct {
	Texture string
}

type RenderSystem struct {
	// 
}

func (rs *RenderSystem) Update(entities map[EntityID]interface{}) {
	for entityID, component := range entities {
		if renderComponent, ok := component.(*RenderComponent); ok {
			// 渲染邏輯
			fmt.Println(entityID, renderComponent)
		}
	}
}

type World struct {
	entities map[EntityID]interface{}
}

func (em *World) CreateEntity(components ...interface{}) EntityID {
	entityID := 0 // 生成唯一值
	em.entities[EntityID(entityID)] = components
	return EntityID(entityID)
}

func (em *World) RemoveEntity(entityID EntityID) {
	delete(em.entities, entityID)
}

func (em *World) AddComponent(entityID EntityID, component interface{}) {
	em.entities[entityID] = component
}

func (em *World) GetComponent(entityID EntityID) interface{} {
	return em.entities[entityID]
}

func main() {
	world := World{entities: make(map[EntityID]interface{})}
	renderSystem := RenderSystem{}

	player := world.CreateEntity(
		&PositionComponent{X: 100, Y: 100},
		&RenderComponent{Texture: "player.png"},
	)

	enemy := world.CreateEntity(
		&PositionComponent{X: 200, Y: 200},
		&RenderComponent{Texture: "enemy.png"},
	)

	// 遊戲循環
	//for {
	renderSystem.Update(world.entities)
	//}
}


這邊再看另外一個範例:A Go Roguelike

待補


上一篇
22. Entity Component System (1)
下一篇
24. ebiten (6)
系列文
HOW TO GO30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言